import sqlalchemy.exc
from flask import Blueprint, request
from Model.models import Recommendation, User, db, ScenicSpot, Tag
from Service.WeatherService import WeatherService
from Service.TravelService import TravelPlanner
from Utils.APIResponse import APIResponse
from Utils.AliyunOSSUtil import upload_to_oss, batch_upload_to_oss
from Utils.TokenUtil import token_required

# 创建一个蓝图(Blueprint)对象
travel_planner_blue = Blueprint("travel_planner", __name__)


@travel_planner_blue.route('/travel/recommendation', methods=['POST'])
@token_required
def get_travel_recommendation(request_user_id):
    data = request.json
    user_data = {
        "目的地": data.get("destination", ''),
        "旅游天数": data.get("travel_days", ''),
        "喜欢的旅游类型": data.get("preferred_activity", ''),
        "不喜欢的旅游类型": data.get("avoid_activity", ''),
        "特别要求": data.get("special_requests", '')
    }
    fcm_token = data.get("fcm_token", '')

    user = User.query.get(request_user_id)
    user.fcm_token = fcm_token

    try:
        from Celery import tasks
        task = tasks.generate_travel_suggestions.delay(user_data, request_user_id)
        if task:  # 确保任务成功启动
            db.session.commit()
            return APIResponse.success(message="推荐结果正在生成中")
        else:
            return APIResponse.error(message="任务启动失败")

    except sqlalchemy.exc.IntegrityError as e:
        db.session.rollback()
        return APIResponse.error({'error': 'Database Integrity Error: ' + str(e)}, status_code=500)
    except sqlalchemy.exc.SQLAlchemyError as e:
        db.session.rollback()
        return APIResponse.error({'error': 'Database Error: ' + str(e)}, status_code=500)


@travel_planner_blue.route('/travel/user/<int:user_id>', methods=['GET'])
@token_required
def get_recommendations(user_id, request_user_id):
    if user_id != request_user_id:
        return APIResponse.error(message={'error': '无权限访问'})
    # 分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    # 查询带有分页的推荐
    paginated_recommendations = Recommendation.query.filter_by(user_id=user_id).paginate(page=page, per_page=per_page,
                                                                                         error_out=False)
    # 将查询结果转换为列表
    recommendations_list = [r.recommendation_data for r in paginated_recommendations.items]

    # 返回包含分页信息的结果
    return APIResponse.success({
        'recommendations': recommendations_list,
        'total': paginated_recommendations.total,
        'pages': paginated_recommendations.pages,
        'current_page': page
    })


@travel_planner_blue.route('/travel/weather', methods=['POST'])
def get_weather():
    city = request.json.get('city', '')
    from app import create_app
    app = create_app()
    weatherService = WeatherService(amap_keys_file=app.config['AMAP_KEY_ROUTE'])
    # 获取天气详情
    weather_details = weatherService.get_weather_details(city)

    if weather_details:
        return APIResponse.success(weather_details)
    else:
        return APIResponse.error({'error': '无法获取天气信息'}, status_code=500)


@travel_planner_blue.route('/travel/scenic/upload', methods=['POST'])
def upload_file():
    file = request.files.get('file')
    text = request.form.get('text', '')

    if not file:
        return APIResponse.error({"error": "No file provided"}, 400)

    # 上传到 OSS
    file_url = upload_to_oss(file, file.filename)

    # 保存信息到数据库
    image_text_detail = ScenicSpot(image_url=file_url, text=text)
    db.session.add(image_text_detail)
    db.session.commit()

    return APIResponse.success({"message": "Uploaded successfully", "url": file_url}, 200)


@travel_planner_blue.route('/travel/scenic', methods=['GET'])
def get_details():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    paginated_items = ScenicSpot.query.paginate(page=page, per_page=per_page, error_out=False)
    items = [{'image_url': item.image_url, 'text': item.text} for item in paginated_items.items]

    return APIResponse.success({
        'items': items,
        'total': paginated_items.total,
        'pages': paginated_items.pages,
        'current_page': paginated_items.page
    })


@travel_planner_blue.route('/travel/nursing', methods=['GET'])
def get_nursing_homes():
    latitude = request.args.get('latitude')
    longitude = request.args.get('longitude')
    radius = request.args.get('radius', 1000, type=int)
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    from app import create_app
    app = create_app()

    if not latitude or not longitude:
        return APIResponse.error({'error': 'Latitude and longitude are required.'})
    travel_planner = TravelPlanner("81aeb512929d8e6b5121064eaed50ad97c44a98f", app.config['AMAP_KEY_ROUTE'])
    all_nursing_homes = travel_planner.get_nearby_nursing_homes(latitude, longitude, radius)

    if all_nursing_homes is None:
        return APIResponse.error({'error': 'Error fetching nursing homes or none found.'})

    # Implementing Pagination
    start = (page - 1) * per_page
    end = start + per_page
    paginated_nursing_homes = all_nursing_homes[start:end]

    total = len(all_nursing_homes)
    total_pages = (total + per_page - 1) // per_page

    return APIResponse.success({
        'items': paginated_nursing_homes,
        'total': total,
        'pages': total_pages,
        'current_page': page
    })


@travel_planner_blue.route('/travel/scenic/batch', methods=['POST'])
def batch_upload():
    files = request.files.getlist('file')
    texts = request.form.getlist('text')

    if not files:
        return APIResponse.error({"error": "No files provided"}, 400)

    if len(files) != len(texts):
        return APIResponse.error({"error": "Each file must have a corresponding text"}, 400)

    urls = batch_upload_to_oss(files)

    # 调用 Celery 任务
    from Celery import tasks
    tasks.batch_upload_task.delay(urls, texts)

    return APIResponse.success({"message": "Upload process initiated"}, 202)


@travel_planner_blue.route('/travel/scenic/<int:scenic_id>', methods=['DELETE'])
def delete_scenic(scenic_id):
    scenic = ScenicSpot.query.get_or_404(scenic_id)
    db.session.delete(scenic)
    db.session.commit()
    return APIResponse.success({'message': 'Scenic deleted successfully'}, 200)


@travel_planner_blue.route('/travel/tags/batch', methods=['POST'])
def batch_create_tags():
    data = request.json
    tag_names = data.get('names')
    if not tag_names:
        return APIResponse.error({'error': 'Tag names are required'}, 400)

        # 使用 Celery 任务异步创建标签
    from Celery import tasks
    tasks.batch_create_tags_task.delay(tag_names)

    return APIResponse.success({"message": "Upload process initiated"}, 202)


@travel_planner_blue.route('/travel/tags', methods=['GET'])
def get_tags():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    paginated_tags = Tag.query.paginate(page=page, per_page=per_page, error_out=False)
    tags = [{'id': tag.id, 'name': tag.name} for tag in paginated_tags.items]

    return APIResponse.success({
        'tags': tags,
        'total': paginated_tags.total,
        'pages': paginated_tags.pages,
        'current_page': paginated_tags.page
    }, 200)


@travel_planner_blue.route('/travel/tags/<int:tag_id>', methods=['DELETE'])
def delete_tag(tag_id):
    tag = Tag.query.get_or_404(tag_id)
    db.session.delete(tag)
    db.session.commit()
    return APIResponse.success({'message': 'Tag deleted successfully'}, 200)
